﻿#region Usings

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Rail.Net.Common;
using Rail.Net.Core.Interfaces.Services;
using Rail.Net.Core.Model;
using Rail.Net.Core.Model.Nonpersistent;
using Rail.Net.Services.KontengentBuchen;
using Rail.Net.Services.KontengentFreigeben;
using Rail.Net.Services.KontengentVerfuegung;
using KontengentVerfuegung_as_pers_anz = Rail.Net.Services.KontengentVerfuegung.as_pers_anz;
using KontengentVerfuegung_header_1_0 = Rail.Net.Services.KontengentVerfuegung.header_1_0;
using KontengentVerfuegung_request_7_0 = Rail.Net.Services.KontengentVerfuegung.request_7_0;
using KontengentBuchen_as_pers_anz = Rail.Net.Services.KontengentBuchen.as_pers_anz;
using KontengentBuchen_header_1_0 = Rail.Net.Services.KontengentBuchen.header_1_0;
using KontengentBuchen_request_7_0 = Rail.Net.Services.KontengentBuchen.request_7_0;
using KontengentFreigeben_as_pers_anz = Rail.Net.Services.KontengentFreigeben.as_pers_anz;
using KontengentFreigeben_header_1_0 = Rail.Net.Services.KontengentFreigeben.header_1_0;
using KontengentFreigeben_request_7_0 = Rail.Net.Services.KontengentFreigeben.request_7_0;

#endregion

namespace Rail.Net.Services
{
    public class ContengentService : IContengentService
    {
        public void GetProducts(SearchModel searchModel, ContengentTrainModel contengentTrainModel,
                                ProductOfferModel productOffer)
        {
            try
            {
                string fromStation = null;
                string toStation = null;
                string border = null;
                string relationNumber = null;
                string kzRichtungH = null;
                var rus = new List<RelationRu>();


                if (contengentTrainModel.IsDomesticOnly)
                {
                    border = "000000000000";
                    relationNumber = "000000";
                    fromStation = "000000000000";
                    toStation = "000000000000";
                    kzRichtungH = "0";
                }
                else
                {
                    rus = contengentTrainModel.Relation.RelationRus.OrderBy(ru => ru.SequenceNumber).ToList();
                    border = contengentTrainModel.Relation.BorderStation;
                    relationNumber = contengentTrainModel.Relation.RelationNumber.ToString().PadLeft(6, '0');
                    if (contengentTrainModel.FirstStation.IsDomestic)
                    {
                        fromStation = contengentTrainModel.FirstStation.Ru.PadLeft(4, '0').PadRight(6, '0') +
                                      contengentTrainModel.FirstStation.DataModel.Tisp.PadLeft(6, '0');
                        toStation = contengentTrainModel.Relation.DestinationStation.PadLeft(12, '0');
                        kzRichtungH = "0";
                    }
                    else
                    {
                        fromStation = contengentTrainModel.Relation.DestinationStation.PadLeft(12, '0');
                        toStation = contengentTrainModel.LastStation.Ru.PadLeft(4, '0').PadRight(6, '0') +
                                    contengentTrainModel.LastStation.DataModel.Tisp.PadLeft(6, '0');
                        kzRichtungH = "1";
                    }
                }


                var contengentName = "EUSP2009 ";
                if (contengentTrainModel.FirstStation.Ru == "83" && contengentTrainModel.LastStation.Ru == "83")
                {
                    contengentName = "BRENNER02";
                }
                else if ((contengentTrainModel.FirstStation.Ru == "83" && contengentTrainModel.LastStation.Ru == "80") ||
                         (contengentTrainModel.FirstStation.Ru == "80" && contengentTrainModel.LastStation.Ru == "83"))
                {
                    contengentName = "BRENNER05";
                }
                else if (contengentTrainModel.FirstStation.Ru == "83" || contengentTrainModel.LastStation.Ru == "83")
                {
                    contengentName = "BRENNER01";
                }
                else if (contengentTrainModel.FirstStation.Ru == "55" ||
                         contengentTrainModel.LastStation.Ru == "55")
                {
                    contengentName = "UNGARN10 ";
                }
                else if (contengentTrainModel.FirstStation.Ru == "54" ||
                         contengentTrainModel.LastStation.Ru == "54")
                {
                    contengentName = "OST2010  ";
                }
                else if (contengentTrainModel.FirstStation.Ru == "51" ||
                         contengentTrainModel.LastStation.Ru == "51")
                {
                    contengentName = "POLEN10  ";
                }
                else if (contengentTrainModel.FirstStation.Ru == "79" ||
                         contengentTrainModel.LastStation.Ru == "79")
                {
                    contengentName = "SLOWEN10 ";
                }
                else if (contengentTrainModel.FirstStation.Ru == "81" &&
                         contengentTrainModel.LastStation.Ru == "81")
                {
                    contengentName = "SPARAUT01";
                }

                var datH = new[]
                               {
                                   searchModel.FromDate.ToString("yyyyMMdd"),
                                   "00000000",
                                   "00000000",
                                   "00000000",
                                   "00000000"
                               };

                var datR = new[]
                               {
                                   searchModel.ToDate.HasValue
                                       ? searchModel.ToDate.Value.ToString("yyyyMMdd")
                                       : "00000000",
                                   "00000000",
                                   "00000000",
                                   "00000000",
                                   "00000000"
                               };

                var zugH = new[]
                               {
                                   "    ",
                                   "    ",
                                   "    ",
                                   "    ",
                                   "    ",
                                   "    ",
                                   "    ",
                                   "    ",
                                   "    ",
                                   "    "
                               };
                var trainIndex = 0;
                foreach (
                    var trainNumber in
                        contengentTrainModel.Connections.Select(c => c.ContengentTrain).Select(c => c.Number).Distinct()
                    )
                {
                    zugH[trainIndex++] = trainNumber;
                }

                var zugR = new[]
                               {
                                   "    ",
                                   "    ",
                                   "    ",
                                   "    ",
                                   "    ",
                                   "    ",
                                   "    ",
                                   "    ",
                                   "    ",
                                   "    "
                               };

                var vwH = new string[5];
                var entfH = new string[5];
                var index = contengentTrainModel.IsDomesticOnly ? 0 : 4;
                vwH[index] = "008100";
                entfH[index] = contengentTrainModel.DomesticDistance.ToString("00000");
                for (var i = 0; i < rus.Count; i++)
                {
                    vwH[i] = rus[i].Ru.CodeLong;
                    entfH[i] = rus[i].Distance.ToString("00000");
                }
                for (var i = contengentTrainModel.IsDomesticOnly ? 1 : rus.Count;
                     i < (contengentTrainModel.IsDomesticOnly ? 5 : 4);
                     i++)
                {
                    vwH[i] = "000000";
                    entfH[i] = "00000";
                }

                var vwR = new[]
                              {
                                  "000000",
                                  "000000",
                                  "000000",
                                  "000000",
                                  "000000"
                              };

                var entfR = new[]
                                {
                                    "00000",
                                    "00000",
                                    "00000",
                                    "00000",
                                    "00000"
                                };


                var comfortClasses = new List<string>
                                         {
                                             Constants.FirstClassNumber,
                                             Constants.SecondClassNumber
                                         };

                foreach (var comfortClass in comfortClasses)
                {
                    var @class = comfortClass;
                    Task.Factory.StartNew(
                        () =>
                        GetProductsWebServiceCall(searchModel, contengentTrainModel, productOffer, fromStation,
                                                  toStation,
                                                  border, relationNumber, kzRichtungH, contengentName, datH, datR, zugH,
                                                  zugR, entfH, entfR, vwH, vwR, @class),
                        TaskCreationOptions.LongRunning | TaskCreationOptions.AttachedToParent);
                }
            }
            catch (Exception e)
            {
                var a = 0;
            }
        }

        private void GetProductsWebServiceCall(SearchModel searchModel,
                                               ContengentTrainModel contengentTrainModel,
                                               ProductOfferModel productOffer,
                                               string fromStation,
                                               string toStation,
                                               string border,
                                               string relationNumber,
                                               string kzRichtungH,
                                               string contengentName,
                                               string[] datH,
                                               string[] datR,
                                               string[] zugH,
                                               string[] zugR,
                                               string[] entfH,
                                               string[] entfR,
                                               string[] vwH,
                                               string[] vwR,
                                               string comfortClass)
        {
            try
            {

                var cService = new KONTINGENTVERFUEGUNGService();
                var contengent = new KONTINGENTVERFUEGUNG
                                     {
                                         header =
                                             new KontengentVerfuegung_header_1_0
                                                 {
                                                     servicekey = 402,
                                                     lenheader = 12,
                                                     lenbuf = 596,
                                                     maxreply = 1130
                                                 },
                                         request =
                                             new KontengentVerfuegung_request_7_0
                                                 {
                                                     as_pers_anz = new[]
                                                                       {
                                                                           new KontengentVerfuegung_as_pers_anz
                                                                               {
                                                                                   pers_art = "E ",
                                                                                   anzahl =
                                                                                       searchModel.Travelers.Count.
                                                                                       ToString(),
                                                                                   filler = ""
                                                                               }
                                                                           ,
                                                                           new KontengentVerfuegung_as_pers_anz
                                                                               {
                                                                                   pers_art = "  ",
                                                                                   anzahl = "   ",
                                                                                   filler = ""
                                                                               }
                                                                           ,
                                                                           new KontengentVerfuegung_as_pers_anz
                                                                               {
                                                                                   pers_art = "  ",
                                                                                   anzahl = "   ",
                                                                                   filler = ""
                                                                               }
                                                                           ,
                                                                           new KontengentVerfuegung_as_pers_anz
                                                                               {
                                                                                   pers_art = "  ",
                                                                                   anzahl = "   ",
                                                                                   filler = ""
                                                                               }
                                                                           ,
                                                                           new KontengentVerfuegung_as_pers_anz
                                                                               {
                                                                                   pers_art = "  ",
                                                                                   anzahl = "   ",
                                                                                   filler = ""
                                                                               }
                                                                           ,
                                                                           new KontengentVerfuegung_as_pers_anz
                                                                               {
                                                                                   pers_art = "  ",
                                                                                   anzahl = "   ",
                                                                                   filler = ""
                                                                               }
                                                                           ,
                                                                           new KontengentVerfuegung_as_pers_anz
                                                                               {
                                                                                   pers_art = "  ",
                                                                                   anzahl = "   ",
                                                                                   filler = ""
                                                                               }
                                                                           ,
                                                                           new KontengentVerfuegung_as_pers_anz
                                                                               {
                                                                                   pers_art = "  ",
                                                                                   anzahl = "   ",
                                                                                   filler = ""
                                                                               }
                                                                           ,
                                                                           new KontengentVerfuegung_as_pers_anz
                                                                               {
                                                                                   pers_art = "  ",
                                                                                   anzahl = "   ",
                                                                                   filler = ""
                                                                               }
                                                                           ,
                                                                           new KontengentVerfuegung_as_pers_anz
                                                                               {
                                                                                   pers_art = "  ",
                                                                                   anzahl = "   ",
                                                                                   filler = ""
                                                                               }
                                                                       },
                                                     dl_konti = "L",
                                                     ktg_nr = contengentName,
                                                     dat_h = datH,
                                                     dat_r = datR,
                                                     zeit_h = "    ",
                                                     zeit_r = "    ",
                                                     zug_h = zugH,
                                                     zug_r = zugR,
                                                     zug_kat_h = "  ",
                                                     zug_kat_r = "  ",
                                                     kz_richtung_h = kzRichtungH,
                                                     kz_richtung_r = "1",
                                                     wkl_h = comfortClass,
                                                     wkl_r = "1",
                                                     abf_h = fromStation,
                                                     abf_r = "000000000000",
                                                     zbf_h = toStation,
                                                     zbf_r = "000000000000",
                                                     grbf_h = border,
                                                     grbf_r = "000000000000",
                                                     rel_h = relationNumber,
                                                     rel_r = "0000000",
                                                     vw_h = vwH,
                                                     vw_r = vwR,
                                                     entf_h = entfH,
                                                     entf_r = entfR,
                                                     kz_fpl_gest_vk = "1",
                                                     rt_pnr = "",
                                                     termbf = "04092",
                                                     app = "001",
                                                     kassa = "099",
                                                     serv = "056",
                                                     v_sys = "07",
                                                     v_kanal = "03"
                                                 }
                                     };
                var response = cService.KONTINGENTVERFUEGUNG(contengent);
                var request = response.request;
                if (request != null)
                {
                    if (request.as_ktg.Length > 0)
                    {
                        var products =
                            from asKtg in
                                request.as_ktg.Where(
                                    ktg =>
                                    !string.IsNullOrEmpty(ktg.preis_pl) && ktg.preis_pl != "0" &&
                                    !string.IsNullOrEmpty(ktg.anz_pl_frei) && ktg.anz_pl_frei != "0")
                            let freeSeats = Int32.Parse(asKtg.anz_pl_frei)
                            let price = (((decimal) Int32.Parse(asKtg.preis_pl))/100)
                            let connections =
                                contengentTrainModel.Connections.Where(
                                    c =>
                                    c.ContengentTrain != null &&
                                    c.ContengentTrain.Number.TrimStart(new[] {' ', '0'}).ToLower() ==
                                    asKtg.zug_nr.TrimStart(new[] {' ', '0'}).ToLower())
                            from product in
                                (from connection in connections
                                 let productIndex = 1
                                 select
                                     new Product2Model(productIndex, searchModel, connection.ContengentSequences,
                                                       comfortClass)
                                         {
                                             ServiceLevel =
                                                 Constants.GlobalComfortClassValues[Constants.ServiceLevelSeat][
                                                     comfortClass == Constants.FirstClassNumber ? 0 : 1],
                                             ServiceLevelGroup = Constants.ServiceLevelSeat,
                                             NumberOfFreeSeats = freeSeats,
                                             Price = price
                                         }
                                )
                            select product;
                        productOffer.Products.AddRange(products);
                    }
                }
            }
            catch (Exception e)
            {
                var a = 9;
            }
        }

        public void Booking()
        {
            var service = new KONTINGENTBUCHENService();
            var result = service.KONTINGENTBUCHEN(new KONTINGENTBUCHEN
                                                      {
                                                          header = new KontengentBuchen_header_1_0
                                                                       {
                                                                           servicekey = 402,
                                                                           lenheader = 12,
                                                                           lenbuf = 596,
                                                                           maxreply = 1130
                                                                       },
                                                          request = new KontengentBuchen_request_7_0
                                                                        {
                                                                            as_pers_anz = new[]
                                                                                              {
                                                                                                  new KontengentBuchen_as_pers_anz
                                                                                                      {
                                                                                                          pers_art =
                                                                                                              "E ",
                                                                                                          anzahl = "",
                                                                                                          filler = ""
                                                                                                      },
                                                                                                  new KontengentBuchen_as_pers_anz
                                                                                                      {
                                                                                                          pers_art =
                                                                                                              "  ",
                                                                                                          anzahl = "   ",
                                                                                                          filler = ""
                                                                                                      },
                                                                                                  new KontengentBuchen_as_pers_anz
                                                                                                      {
                                                                                                          pers_art =
                                                                                                              "  ",
                                                                                                          anzahl = "   ",
                                                                                                          filler = ""
                                                                                                      },
                                                                                                  new KontengentBuchen_as_pers_anz
                                                                                                      {
                                                                                                          pers_art =
                                                                                                              "  ",
                                                                                                          anzahl = "   ",
                                                                                                          filler = ""
                                                                                                      },
                                                                                                  new KontengentBuchen_as_pers_anz
                                                                                                      {
                                                                                                          pers_art =
                                                                                                              "  ",
                                                                                                          anzahl = "   ",
                                                                                                          filler = ""
                                                                                                      },
                                                                                                  new KontengentBuchen_as_pers_anz
                                                                                                      {
                                                                                                          pers_art =
                                                                                                              "  ",
                                                                                                          anzahl = "   ",
                                                                                                          filler = ""
                                                                                                      },
                                                                                                  new KontengentBuchen_as_pers_anz
                                                                                                      {
                                                                                                          pers_art =
                                                                                                              "  ",
                                                                                                          anzahl = "   ",
                                                                                                          filler = ""
                                                                                                      },
                                                                                                  new KontengentBuchen_as_pers_anz
                                                                                                      {
                                                                                                          pers_art =
                                                                                                              "  ",
                                                                                                          anzahl = "   ",
                                                                                                          filler = ""
                                                                                                      },
                                                                                                  new KontengentBuchen_as_pers_anz
                                                                                                      {
                                                                                                          pers_art =
                                                                                                              "  ",
                                                                                                          anzahl = "   ",
                                                                                                          filler = ""
                                                                                                      },
                                                                                                  new KontengentBuchen_as_pers_anz
                                                                                                      {
                                                                                                          pers_art =
                                                                                                              "  ",
                                                                                                          anzahl = "   ",
                                                                                                          filler = ""
                                                                                                      }
                                                                                              },
                                                                            dl_konti = "L",
                                                                            ktg_nr = "",
                                                                            dat_h = "",
                                                                            dat_r = "",
                                                                            zeit_h = "    ",
                                                                            zeit_r = "    ",
                                                                            zug_h = "",
                                                                            zug_r = "",
                                                                            zug_kat_h = "  ",
                                                                            zug_kat_r = "  ",
                                                                            kz_richtung_h = "",
                                                                            kz_richtung_r = "1",
                                                                            wkl_h = "1",
                                                                            wkl_r = "1",
                                                                            abf_h = "",
                                                                            abf_r = "000000000000",
                                                                            zbf_h = "",
                                                                            zbf_r = "000000000000",
                                                                            grbf_h = "",
                                                                            grbf_r = "000000000000",
                                                                            rel_h = "",
                                                                            rel_r = "0000000",
                                                                            vw_h = new string[5],
                                                                            vw_r = new string[5],
                                                                            entf_h = new string[5],
                                                                            entf_r = new string[5],
                                                                            kz_fpl_gest_vk = "1",
                                                                            rt_pnr = "",
                                                                            termbf = "04092",
                                                                            app = "001",
                                                                            kassa = "099",
                                                                            serv = "056",
                                                                            v_sys = "07",
                                                                            v_kanal = "03",
                                                                            ktg_sub_nr = "",
                                                                            ref_nr_ktg_v = ""
                                                                        }
                                                      });
        }

        public void Rollback()
        {
            var service = new KONTINGENTFREIGEBENService();
            var result = service.KONTINGENTFREIGEBEN(new KONTINGENTFREIGEBEN
                                                         {
                                                             header = new KontengentFreigeben_header_1_0
                                                                          {
                                                                              servicekey = 402,
                                                                              lenheader = 12,
                                                                              lenbuf = 596,
                                                                              maxreply = 1130
                                                                          },
                                                             request = new KontengentFreigeben_request_7_0
                                                                           {
                                                                               as_pers_anz = new[]
                                                                                                 {
                                                                                                     new KontengentFreigeben_as_pers_anz
                                                                                                         {
                                                                                                             pers_art =
                                                                                                                 "E ",
                                                                                                             anzahl = "",
                                                                                                             filler = ""
                                                                                                         },
                                                                                                     new KontengentFreigeben_as_pers_anz
                                                                                                         {
                                                                                                             pers_art =
                                                                                                                 "  ",
                                                                                                             anzahl =
                                                                                                                 "   ",
                                                                                                             filler = ""
                                                                                                         },
                                                                                                     new KontengentFreigeben_as_pers_anz
                                                                                                         {
                                                                                                             pers_art =
                                                                                                                 "  ",
                                                                                                             anzahl =
                                                                                                                 "   ",
                                                                                                             filler = ""
                                                                                                         },
                                                                                                     new KontengentFreigeben_as_pers_anz
                                                                                                         {
                                                                                                             pers_art =
                                                                                                                 "  ",
                                                                                                             anzahl =
                                                                                                                 "   ",
                                                                                                             filler = ""
                                                                                                         },
                                                                                                     new KontengentFreigeben_as_pers_anz
                                                                                                         {
                                                                                                             pers_art =
                                                                                                                 "  ",
                                                                                                             anzahl =
                                                                                                                 "   ",
                                                                                                             filler = ""
                                                                                                         },
                                                                                                     new KontengentFreigeben_as_pers_anz
                                                                                                         {
                                                                                                             pers_art =
                                                                                                                 "  ",
                                                                                                             anzahl =
                                                                                                                 "   ",
                                                                                                             filler = ""
                                                                                                         },
                                                                                                     new KontengentFreigeben_as_pers_anz
                                                                                                         {
                                                                                                             pers_art =
                                                                                                                 "  ",
                                                                                                             anzahl =
                                                                                                                 "   ",
                                                                                                             filler = ""
                                                                                                         },
                                                                                                     new KontengentFreigeben_as_pers_anz
                                                                                                         {
                                                                                                             pers_art =
                                                                                                                 "  ",
                                                                                                             anzahl =
                                                                                                                 "   ",
                                                                                                             filler = ""
                                                                                                         },
                                                                                                     new KontengentFreigeben_as_pers_anz
                                                                                                         {
                                                                                                             pers_art =
                                                                                                                 "  ",
                                                                                                             anzahl =
                                                                                                                 "   ",
                                                                                                             filler = ""
                                                                                                         },
                                                                                                     new KontengentFreigeben_as_pers_anz
                                                                                                         {
                                                                                                             pers_art =
                                                                                                                 "  ",
                                                                                                             anzahl =
                                                                                                                 "   ",
                                                                                                             filler = ""
                                                                                                         }
                                                                                                 },
                                                                               app = "",
                                                                               dl_konti = "",
                                                                               kassa = "",
                                                                               ref_nr_ktg = "",
                                                                               serv = "",
                                                                               termbf = "",
                                                                               v_kanal = "",
                                                                               v_sys = ""
                                                                           }
                                                         });
        }
    }
}